package com.yzd.learnjava.concurrency;

import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import com.yzd.learnjava.util.Print;

public class ActiveObjectDemo {
	private ExecutorService exec = Executors.newSingleThreadExecutor();
	private Random random = new Random(47);
	private void pause(int factor) {
		try {
			TimeUnit.MICROSECONDS.sleep(100 + random.nextInt(factor));
		} catch (InterruptedException e) {
			Print.print("sleep() interrupted");
			e.printStackTrace();
		}
	}
	
	public Future<Integer> calculateInt(final int x , final int y){
		return exec.submit(new Callable<Integer>() {
			public Integer call() {
				Print.print("starting " + x + " + " + y);
				pause(500);
				return x + y;
			}
		});
	}
	
	public Future<Float> calculateFloat(final float x , final float y){
		return exec.submit(new Callable<Float>() {
			public Float call() {
				Print.print("starting " + x + " + " + y);
				pause(500);
				return x + y;
			}
		});
	}
	
	public void shutDown() {
		exec.shutdown();
	}
	
	public static void main(String[] args) {
		ActiveObjectDemo d1 = new ActiveObjectDemo();
		List<Future<?>> results = new CopyOnWriteArrayList<Future<?>>();
		for(float f =0.0f; f < 1.0f; f += 0.2f ) {
			results.add(d1.calculateFloat(f, f));
		}
		for(int i = 0; i < 5; i++) {
			results.add(d1.calculateInt(i, i));
		}
		
		Print.print("All asynch calls made");
		while(results.size() > 0) {
			for(Future<?> f : results) {
				if(f.isDone()) {
					try {
						Print.print(f.get());
					} catch (Exception e) {
						e.printStackTrace();
					}
					results.remove(f);
				}
			}
		}
		d1.shutDown();
	}
}















